package com.army.qinhongjunai.utils;

import com.army.qinhongjunai.slice.MainAbilitySlice;
import ohos.ai.cv.common.*;
import ohos.ai.cv.text.ITextDetector;
import ohos.ai.cv.text.Text;
import ohos.ai.cv.text.TextConfiguration;
import ohos.ai.cv.text.TextDetectType;
import ohos.app.Context;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.global.resource.ResourceManager;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class WordRecognition {
//    private static final boolean IS_ASYNC = true;
    private static final boolean IS_ASYNC = false;
    private static final int IS_ASYNC_CODE = 700;
    private Context slice;
    private ITextDetector textDetector;
    private PixelMap pixelMap;
    private MainAbilitySlice.MyEventHandle handle;
    private int[] pictureLists;
    private int mediaId;
    private Map maps = new HashMap<>();
    private int index;
    private int result;

    public void setParams(Context context, int[] pictureIds, MainAbilitySlice.MyEventHandle myEventHandle) {
        LogUtil.info("WordRecognition", "setParams获取参数 " + pictureIds[0]);
        slice = context;
        pictureLists = pictureIds;
        handle = myEventHandle;
    }

    public void wordRecognition(Context context, int resId, MainAbilitySlice.MyEventHandle handle) {
        LogUtil.info("WordRecognition", "wordRecognition检测图片 " + resId);
        mediaId = resId;
        // 实例化ITextDetector接口
        textDetector = VisionManager.getTextDetector(context);
        // 1. 实例化VisionImage对象image, 并传入待检测图片pixelMap
        pixelMap = getPixelMap(resId);
        VisionImage image = VisionImage.fromPixelMap(pixelMap);
        // 2. 定义VisionCallback<Text>回调, 异步模式下用到
        VisionCallback<Text> visionCallback = getVisionCallback();
        // 3. 定义ConnectionCallback回调, 实现连接能力引擎成功与否后的操作
        ConnectionCallback connectionCallback = getConnectionCallback(image, visionCallback);
        // 4. 建立与能力引擎的连接
        VisionManager.init(context, connectionCallback);
    }

    // 1. 实例化VisionImage对象image, 并传入待检测图片pixelMap
    private PixelMap getPixelMap(int resId) {
        LogUtil.info("WordRecognition", "1. 实例化VisionImage对象image, 并传入待检测图片pixelMap");
        ResourceManager manager = slice.getResourceManager();
        byte[] datas = new byte[0];
        try{
            Resource resource = manager.getResource(resId);
            datas = readBytes(resource);
            resource.close();
        }catch (IOException | NotExistException e) {
            LogUtil.error("检测图片", e.getLocalizedMessage());
        }

        ImageSource.SourceOptions srcOptions = new ImageSource.SourceOptions();
        srcOptions.formatHint = "image/jpg";
        ImageSource imageSource = ImageSource.create(datas, srcOptions);

        ImageSource.DecodingOptions decOptions = new ImageSource.DecodingOptions();
        decOptions.desiredSize = new Size(0,0);
        decOptions.desiredRegion = new Rect(0, 0, 0, 0);
        decOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
        pixelMap = imageSource.createPixelmap(decOptions);

        return pixelMap;
    }

    private static byte[] readBytes(Resource resource) {
        final int bufferSize = 1024;
        final int ioEnd = -1;

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffers = new byte[bufferSize];
        byte[] results = new byte[0];

        while (true) {
            try{
                int readLen = resource.read(buffers, 0, bufferSize);
                if (readLen == ioEnd) {
                    results = output.toByteArray();
                    break;
                }
                output.write(buffers, 0, readLen);
            }catch (IOException e) {
                LogUtil.error("OrcAbilitySlice.getPixelMap", "read resource failed ");
                break;
            }finally {
                try{
                    output.close();
                }catch (IOException e) {
                    LogUtil.error("OrcAbilitySlice.getPixelMap", "close output failed");
                }
            }
        }
        return results;
    }

    // 2. 定义VisionCallback<Text>回调, 异步模式下用到
    private VisionCallback getVisionCallback() {
        LogUtil.info("WordRecognition", "2. 定义VisionCallback<Text>回调, 异步模式下用到");
        return new VisionCallback<Text>() {
            @Override
            public void onResult(Text text) {
                LogUtil.info("getVisionCallback", "onResult: " + text.getValue());
                sendResult(text.getValue());
            }

            @Override
            public void onError(int i) {
                LogUtil.error("WordRecognition.getVisionCallback", "vision callback error");
            }

            @Override
            public void onProcessing(float v) {
            }
        };
    }
    public void sendResult(String value) {
        LogUtil.info("sendResult", "value: " + value);
        if (textDetector != null) {
            textDetector.release();
        }
        if (pixelMap != null) {
            pixelMap.release();
            pixelMap = null;
            VisionManager.destroy();
        }
        if (value != null) {
            maps.put(mediaId, value);
        }

        LogUtil.info("sendResult", "maps: " + maps);
        if ((maps != null) && (maps.size() == pictureLists.length)) {
            InnerEvent event = InnerEvent.get(1, 0, maps);
            handle.sendEvent(event);
        }else {
            wordRecognition(slice, pictureLists[index], handle);
            index++;
        }
    }

    // 3. 定义ConnectionCallback回调, 实现连接能力引擎成功与否后的操作
    private ConnectionCallback getConnectionCallback(VisionImage image, VisionCallback<Text> visionCallback) {
        LogUtil.info("WordRecognition", "3. 定义ConnectionCallback回调, 实现连接能力引擎成功与否后的操作");
        return new ConnectionCallback() {
            @Override
            public void onServiceConnect() {
                LogUtil.info("WordRecognition", "3.1. 连接开始");
                Text text = new Text();

                // 通过TextConfiguration配置textDetector()方法的运行参数
                TextConfiguration.Builder builder = new TextConfiguration.Builder();
                builder.setProcessMode(VisionConfiguration.MODE_IN); // 同进程调用
                builder.setDetectType(TextDetectType.TYPE_TEXT_DETECT_FOCUS_SHOOT); // 自然场景OCR
                builder.setLanguage(TextConfiguration.AUTO);
                TextConfiguration configuration = builder.build();
                textDetector.setVisionConfiguration(configuration);

                // 调用ITextDetector的detect()方法
                if (IS_ASYNC) {
                    result = textDetector.detect(image, null, visionCallback); // 异步调用
                }else {
                    LogUtil.info("getConnectionCallback", "同步调用^^^^^^");
                    result = textDetector.detect(image, text, null); // 同步调用
                    LogUtil.info("getConnectionCallback", "同步调用结果: " + result);
                    sendResult(text.getValue());
                }
//                if (!IS_ASYNC) {
//                    int result2 = textDetector.detect(image, text, null); // 同步
//                    sendResult(text.getValue());
//                } else {
//                    int result2 = textDetector.detect(image, null, visionCallback); // 异步
//                }
                LogUtil.info("WordRecognition", "3.1. 连接结束");
            }

            @Override
            public void onServiceDisconnect() {
                LogUtil.info("WordRecognition", "3.1. 断开开始");
                // 释放资源
                if ((IS_ASYNC && IS_ASYNC_CODE == result) || (!IS_ASYNC && result == 0)) {
                    LogUtil.info("WordRecognition", "3.1. 释放textDetector");
                    textDetector.release();
                }
                if (pixelMap != null) {
                    LogUtil.info("WordRecognition", "3.1. 释放pixelMap");
                    pixelMap.release();
                    pixelMap = null;
                }
//                if ((!IS_ASYNC && (result == 0)) || (IS_ASYNC && (result == IS_ASYNC_CODE))) {
//                    LogUtil.info("WordRecognition", "3.1. 释放textDetector");
//                    textDetector.release();
//                }
//                if (pixelMap != null) {
//                    LogUtil.info("WordRecognition", "3.1. 释放pixelMap");
//                    pixelMap.release();
//                    pixelMap = null;
//                }
                VisionManager.destroy();
                LogUtil.info("WordRecognition", "3.1. 断开结束");
            }
        };
    }
}
